package edu.xhu.search.job;

import edu.xhu.model.search.constant.SearchConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Component
@RequiredArgsConstructor
@Slf4j
public class SearchTermJob {

    private final StringRedisTemplate redisTemplate;

    /**
     * 每秒种刷新热搜缓存
     * 清除 zset 中热度为 0 的词条
     * 清除 hset 中不存在于 zset 的词条
     */
    @Scheduled(fixedRate = 1000)
    private void refreshHotSearchCache() {
        // 获取分数为 0 的元素
        // 获取 Redis 有序集合（zset）中指定分数范围内的元素，并包含每个元素的分数。
        Set<ZSetOperations.TypedTuple<String>> zeroScoreElements = redisTemplate.opsForZSet().rangeByScoreWithScores(SearchConstant.HOT_SEARCH_RANKING_ZSET, 0, 0);

        List<String> removedElements = new ArrayList<>(); // hset 中不存在于 zset 的词条

        // 1. 清理 zset 中分数为 0 的元素
        if (zeroScoreElements != null && !zeroScoreElements.isEmpty()) {
            // 开始管道操作
            redisTemplate.executePipelined((RedisCallback<?>) (connection) -> {
                for (ZSetOperations.TypedTuple<String> element : zeroScoreElements) {
                    String value = element.getValue();
                    removedElements.add(value);
                    connection.zRem(redisTemplate.getStringSerializer().serialize(SearchConstant.HOT_SEARCH_RANKING_ZSET),
                            redisTemplate.getStringSerializer().serialize(value));
                }
                return null;
            });
        }

        // 2. 清理 hset 中不存在于 zset 的词条
        redisTemplate.executePipelined((RedisCallback<?>) (connection) -> {
            for (String removedElement : removedElements) {
                connection.hDel(
                        redisTemplate.getStringSerializer().serialize(SearchConstant.HOT_SEARCH_UPDATE_TIME_HSET),
                        redisTemplate.getStringSerializer().serialize(removedElement)
                );
            }
            return null;
        });

        System.out.println("定时任务：refreshHotSearchCache");
    }
}
